﻿#include "RecordPicture.h"

RecordPicture::RecordPicture(
	int frame_size_x,
	int frame_size_y,
	double frame_rate,
	Color body_color,
	int body_radius,
	std::string picture_path,
	int picture_radius,
	Color center_color,
	int center_radius,
	double dps,
	double brightness
) :MLObj(frame_size_x, frame_size_y, frame_rate) {
	std::cout << "正在初始化唱片图片……\n\n" << std::endl;
	cv::Mat layer0 = cv::imread("./Images/Record/Layer0.png", cv::IMREAD_UNCHANGED);
	cv::Mat layer1 = cv::imread("./Images/Record/Layer1.png", cv::IMREAD_UNCHANGED) * brightness;
	cv::Mat layer2 = cv::imread("./Images/Record/Layer2.png", cv::IMREAD_UNCHANGED);
	cv::Mat layer3 = cv::imread("./Images/Record/Layer3.png", cv::IMREAD_UNCHANGED);
	cv::Mat recordPicture = cv::imread(picture_path, cv::IMREAD_UNCHANGED) * brightness;
	if (recordPicture.empty()) {
		throw "无法打开唱片插图。";
	}
	if (recordPicture.channels() == 3) {
		cv::cvtColor(recordPicture, recordPicture, cv::COLOR_BGR2RGBA);
	}
	else {
		cv::cvtColor(recordPicture, recordPicture, cv::COLOR_BGRA2RGBA);
	}
	cv::resize(layer0, layer0, cv::Size(body_radius * 2, body_radius * 2));
	cv::resize(layer1, layer1, cv::Size(body_radius * 2, body_radius * 2));
	cv::resize(layer2, layer2, cv::Size(picture_radius * 2, picture_radius * 2));
	cv::cvtColor(layer0, layer0, cv::COLOR_BGRA2RGBA);
	cv::cvtColor(layer1, layer1, cv::COLOR_BGRA2RGBA);
	cv::cvtColor(layer2, layer2, cv::COLOR_BGRA2RGBA);
	cv::cvtColor(layer3, layer3, cv::COLOR_BGRA2RGBA);
	if (center_radius > 0) {
		cv::resize(layer3, layer3, cv::Size(center_radius * 2, center_radius * 2));
	}
	layer0.convertTo(layer0, CV_64FC4);
	layer0 /= 127.5;
	std::vector<cv::Mat> channels0;
	cv::split(layer0, channels0);
	channels0[0] *= (double)body_color.x * brightness;
	channels0[1] *= (double)body_color.y * brightness;
	channels0[2] *= (double)body_color.z * brightness;
	channels0[3] *= 255;
	cv::merge(channels0, layer0);
	layer0.convertTo(layer0, CV_8UC4);
	channels0.clear();
	layer3.convertTo(layer3, CV_64FC4);
	std::vector<cv::Mat> channels1;
	cv::split(layer3, channels1);
	channels1[0] *= center_color.x * brightness / 255.0;
	channels1[1] *= center_color.y * brightness / 255.0;
	channels1[2] *= center_color.z * brightness / 255.0;
	channels1[3] /= 255.0;
	if (center_radius == 0) {
		channels1[3] -= 1;
	}
	cv::merge(channels1, layer3);
	layer3.convertTo(layer3, CV_8UC4);
	double resize_rate = std::max<double>((double)picture_radius * 2 / recordPicture.cols, (double)picture_radius * 2 / recordPicture.rows);
	cv::resize(recordPicture, recordPicture, cv::Size(recordPicture.cols * resize_rate, recordPicture.rows * resize_rate));
	recordPicture = recordPicture(cv::Range((recordPicture.rows - picture_radius * 2) / 2, (recordPicture.rows + picture_radius * 2) / 2), cv::Range((recordPicture.cols - picture_radius * 2) / 2, (recordPicture.cols + picture_radius * 2) / 2));
	GLuint glsl = Utils::activateShader("./GLSL/RecordVertex.glsl", "./GLSL/RecordFragment.glsl");
	_record = Drawer::initRecord(layer0, layer1, layer2, layer3, recordPicture, glsl, dps, frame_size_x, frame_size_y, frame_rate);
	_mix_glsl = Utils::activateShader("./GLSL/MixVertex.glsl", "./GLSL/MixFragment.glsl");
}

void RecordPicture::get_frame(size_t frame_index, MLFrame& frame) {
	Drawer::drawRecord(_record);
	frame.mix(_record.fbo, _record.fbo_texture, _record.rbo, _mix_glsl);
}